/**
 * 
 */
package org.statewalker.parser.xhtml.tokenizer;

import org.statewalker.tokenizer.CharStream;
import org.statewalker.tokenizer.ITokenizer;
import org.statewalker.tokenizer.StreamToken;
import org.statewalker.tokenizer.CharStream.Marker;
import org.statewalker.tokenizer.text.TextTokenizer;
import org.statewalker.tokenizer.xml.TagToken;
import org.statewalker.tokenizer.xml.TagTokenizer;

/**
 * @author kotelnikov
 */
public abstract class AbstractEndPCDATATokenizer implements ITokenizer {

    private String fTagName;

    private TagTokenizer fTagTokenizer;

    private TextTokenizer fTextTokenizer;

    /**
     * @param key
     * @param textDictionary
     */
    public AbstractEndPCDATATokenizer(
        String tagName,
        TagTokenizer tagTokenizer,
        TextTokenizer textTokenizer) {
        fTagName = tagName;
        fTagTokenizer = tagTokenizer;
        fTextTokenizer = textTokenizer;
    }

    /**
     * @see org.statewalker.tokenizer.ITokenizer#read(org.statewalker.tokenizer.CharStream)
     */
    public StreamToken read(CharStream stream) {
        StreamToken token = readCloseScriptTag(stream);
        if (token == null) {
            token = fTextTokenizer.read(stream);
        }
        return token;
    }

    /**
     * @param stream
     * @return the script close token or null
     */
    private StreamToken readCloseScriptTag(CharStream stream) {
        if (stream.getChar() != '<')
            return null;
        TagToken result = null;
        Marker marker = stream.markPosition();
        try {
            result = (TagToken) fTagTokenizer.read(stream);
            if (result != null) {
                String name = result.getName();
                if (!result.isClose() || !fTagName.equals(name.toLowerCase())) {
                    result = null;
                }
            }
            return result;
        } finally {
            marker.close(result == null);
        }
    }

}
